﻿using Dm.util;
using LPLS.Commons.Enums;
using LPLS.DBEntities.ConfigModels.DataCollectionConfigModule.DataCollectionRuleEdgeModule;
using LPLS.DBInterface.ConfigModels.DataCollectionConfigModule.DataCollectionRuleEdgeModule;
using LPLS.DBInterface.ConfigModels.DataCollectionConfigModule.PLC;
using Newtonsoft.Json;
using Prism.Commands;
using Prism.Dialogs;
using Prism.Mvvm;
using RulesEngine.Models;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using JsonSerializer = System.Text.Json.JsonSerializer;

namespace DataCollectionVarConfig.ViewModels
{
    public class DataCollectionPLCRuleEdgeViewModel : BindableBase
    {
        IDataCollectionRuleConfigService _dataCollectionRuleConfigService;
        IPLCVarPropertyConfigService _pLCVarPropertyConfigService;
        private readonly IDialogService _dialogService;

        private readonly IDataCollectionOPCUAConfigService _dataCollectionOPCUAConfigService1;
        public DataCollectionPLCRuleEdgeViewModel(IPLCVarPropertyConfigService pLCVarPropertyConfigService,
            IDataCollectionRuleConfigService dataCollectionRuleConfigService
            , IDialogService dialogService
            , IDataCollectionOPCUAConfigService dataCollectionOPCUAConfigService
            )
        {
            _dialogService = dialogService;
            _pLCVarPropertyConfigService = pLCVarPropertyConfigService;
            _dataCollectionRuleConfigService = dataCollectionRuleConfigService;
            _dataCollectionOPCUAConfigService1= dataCollectionOPCUAConfigService;
            DataCollectionVarConfigEvent.DataCollectionDeviceChangeEvent += DataCollectionVarConfigEvent_DataCollectionDeviceChangeEvent;
            LoadRules();
            AddCommand = new DelegateCommand(AddData);


        }


        private List<DataCollectionRuleConfig> AlreadyRuleDate { get; set; }


        /// <summary>
        /// 加载已经配置过的数据
        /// </summary>
        private void LoadAlreadyRuleConfig()
        {

            if (CompentDic != null)
            {
                foreach (var item in CompentDic)
                {
                    item.Value.Clear();
                }
            }
            CompentDic.Clear();
            CompentDic = new Dictionary<string, ObservableCollection<ConditionItem>>();
            AlreadyRuleDate = new List<DataCollectionRuleConfig>();


            var res =
              _dataCollectionRuleConfigService.GetData(eventModel.DeviceModel.ID, eventModel.DeviceComponent.ID).ToList()
                .FirstOrDefault()?.Rules;

            if (res == null)
            {
                Message = "未能找到该器件的规则";

                return;
            }
            else
            {
                AlreadyRuleDate = res;
            }
            if (ConditionList != null && ConditionList.Count > 0)
            {
                ConditionList.Clear();
            }

            foreach (var item2 in AlreadyRuleDate)
            {

                List<ConditionItem> li = new List<ConditionItem>();
                ///获取到
                var dataExpressJson = item2.ExpressionJson;
                List<ExpressItem> expressli = new List<ExpressItem>();
                if (dataExpressJson != null)
                {
                    expressli = JsonSerializer.Deserialize<List<ExpressItem>>(dataExpressJson);
                }

                ///这是加载的PLC的变量
                var plcRuleData = _pLCVarPropertyConfigService.GetData().Where(e => e.DeviceID == eventModel.DeviceModel.ID && e.ComponentID == eventModel.DeviceComponent.ID).ToList();

                foreach (var item in plcRuleData)
                {
                    ConditionItem model = new ConditionItem();
                    var d = expressli.Where(e => e.Name == item.VarName).ToList()?.FirstOrDefault();
                    if (d != null)
                    {
                        model.IsCheck = true;
                        model.Value = d.Value;
                    }
                    else
                    {

                        model.IsCheck = false;
                        model.Value = "";
                    }
                    model.PLCProperty = item.VarName;
                    model.VarType = item.VarTypeName;
                    model.PropertyID = item.ID;
                    li.Add(model);

                }
                CompentDic.Add(item2.RuleName, new ObservableCollection<ConditionItem>(li));

            }

        }




        private DataCollectionVarConfigEventModel eventModel { get; set; }


        private void DataCollectionVarConfigEvent_DataCollectionDeviceChangeEvent(DataCollectionVarConfigEventModel obj)
        {
            eventModel = obj;
            LoadAlreadyRuleConfig();
            LoadOPCUAModel();
        }
        /// <summary>
        /// 部件字典
        /// </summary>
        public Dictionary<string, ObservableCollection<ConditionItem>> CompentDic = new Dictionary<string, ObservableCollection<ConditionItem>>();

        /// <summary>
        /// 加载该器件下的该规则的详细信息
        /// </summary>
        private async Task LoadAlreayRuleData()
        {
          
              ;
            if (CompentDic.ContainsKey(StatusEnumHelper.GetStatusEnumByDescription(SelectRule).toString()))
            {
                ConditionList = CompentDic[StatusEnumHelper.GetStatusEnumByDescription(SelectRule).toString()];
                return;
            }
            // 准备对话框参数
            var parameters = new DialogParameters();
            parameters.Add("dialogMessage", "该部件尚未设置该规则是否继续！");
            _dialogService.ShowDialog("MyDialogView", parameters, result =>
            {
                if (result.Result == ButtonResult.OK)
                {
                 
                    List<ConditionItem> li = new List<ConditionItem>();
                    ///获取到
                    var dataExpressJson = AlreadyRuleDate?.Where(e => e.RuleName == SelectRule)?.FirstOrDefault()?.ExpressionJson;
                    List<ExpressItem> expressli = new List<ExpressItem>();
                    if (dataExpressJson != null)
                    {
                        expressli = JsonSerializer.Deserialize<List<ExpressItem>>(dataExpressJson);
                    }

                    ///这是加载的PLC的变量
                    var plcRuleData = _pLCVarPropertyConfigService.GetData().Where(e => e.DeviceID == eventModel.DeviceModel.ID && e.ComponentID == eventModel.DeviceComponent.ID).ToList();

                    if (plcRuleData.Count == 0)
                    {
                        Message = "该部件未添加相应PLC采集变量";

                        return;
                    }
                    foreach (var item in plcRuleData)
                    {
                        ConditionItem model = new ConditionItem();
                        var d = expressli.Where(e => e.Name == item.VarName).ToList()?.FirstOrDefault();
                        if (d != null)
                        {
                            model.IsCheck = true;
                            model.Value = d.Value;
                        }
                        else
                        {

                            model.IsCheck = false;
                            model.Value = "";
                        }
                        model.PLCProperty = item.VarName;
                        model.VarType = item.VarTypeName;
                        model.PropertyID = item.ID;
                        li.Add(model);

                    }
                    if (!CompentDic.Keys.Contains(SelectRule))
                    {
                        CompentDic.Add(SelectRule, new ObservableCollection<ConditionItem>(li));

                    }
                   
                    ConditionList = CompentDic[SelectRule];
                }
                else if (result.Result == ButtonResult.Cancel)
                {
                    ConditionList = new ObservableCollection<ConditionItem>();
                    // 用户点击取消后的操作
                }
            });
           


        }

        private ObservableCollection<ConditionItem> _ConditionList;
        /// <summary>
        /// 条件
        /// </summary>
        public ObservableCollection<ConditionItem> ConditionList
        {
            get { return _ConditionList; }
            set
            {
                SetProperty(ref _ConditionList, value);

            }
        }




        private string _Message;

        public string Message
        {
            get { return _Message; }
            set
            {
                SetProperty(ref _Message, value);

            }
        }













        private ObservableCollection<string> _Rules;

        /// <summary>
        /// 规则结果
        /// </summary>
        public ObservableCollection<string> Rules
        {
            get { return _Rules; }
            set { _Rules = value; }
        }

        /// <summary>
        /// 加载规则结果：状态集合
        /// </summary>
        private void LoadRules()
        {

            List<string> rules = new List<string>();
            var (enumvalues, enumvalueInts, decs) = StatusEnumHelper.GetEnumCollections();

            foreach (var item in decs)
            {


                rules.Add(item.ToString());

            }

            this.Rules = new ObservableCollection<string>(rules);

        }







        private string _WorkFlowName;

        public string WorkFlowName
        {
            get { return _WorkFlowName; }
            set
            {
                SetProperty(ref _WorkFlowName, value);
            }
        }


        #region Command

        public DelegateCommand AddCommand { get; }

        public DelegateCommand UpdateCommand { get; }


       

        /// <summary>
        /// 添加数据
        /// </summary>
        private void AddData()
        {
            Message = "正在添加";
           SaveOPCUAModel();;

         
                WorkFlowName = $"{eventModel.DeviceModel.DeviceName}-{eventModel.DeviceComponent.ComponentName}";
                var dbrules = new List<DataCollectionRuleConfig>();
                List<Workflow> workflows = new List<Workflow>();
                Workflow workflow = new Workflow();
                workflow.WorkflowName = WorkFlowName;
                List<Rule> rules = new List<Rule>();
                workflow.Rules = rules;
                //1.需要数据转换

                var insertdata = CompentDic;
                ///再此创建Rule
                foreach (var item in CompentDic)
                {
                    var rulename = item.Key;
                    var ruledata = item.Value;
                    if (ruledata.Count > 0)
                    {
                        StringBuilder sb = new StringBuilder();
                        List<ExpressItem> expressli = new List<ExpressItem>();
                        foreach (var item2 in ruledata)
                        {
                            ///加入匹配规则的则加入  表达式
                            if (item2.IsCheck)
                            {
                                //获取 变量的值  
                                var var1 = item2.PLCProperty;
                                sb.Append(var1 + " == " + item2.Value.ToLower() + " and ");
                                ExpressItem expressItem = new ExpressItem();
                                expressItem.Name = var1;
                                expressItem.Value = item2.Value;
                                expressli.Add(expressItem);
                            }
                        }
                        var expression = sb.ToString();
                        if (expression.Length > 4 && !string.IsNullOrEmpty(expression))
                        {

                            #region 数据库操作  对DataCollectionRuleConfig 进行赋值 然后加入DataCollectionWorkFlowConfig的规则中
                            DataCollectionRuleConfig model = new DataCollectionRuleConfig();
                            model.ID = Guid.NewGuid();
                            model.RuleName = rulename.ToString();
                            model.Expression = expression.Remove(expression.Length - 4);
                            model.ExpressionJson = JsonSerializer.Serialize(expressli, new JsonSerializerOptions { WriteIndented = true }); ;
                            model.SuccessEvent = StatusEnumHelper.GetStatusEnumByDescription( rulename.ToString()).toString();
                            dbrules.Add(model);
                            #endregion
                            #region 工作流操作
                            Rule rule = new Rule();
                            rule.RuleName = rulename.toString();
                            expression = expression.Remove(expression.Length - 4);
                            rule.Expression = expression;
                            rule.SuccessEvent = StatusEnumHelper.GetStatusEnumByDescription(rulename.ToString()).toString();
                            rule.RuleExpressionType = RuleExpressionType.LambdaExpression;
                            rules.Add(rule);
                            #endregion
                        }
                    }
                }
                if (rules.Count > 0)
                {

                    #region 创建工作流  创建json
                    workflows.Add(workflow);
                    //创建json
                    ///
                    string json = JsonConvert.SerializeObject(new[] { workflow }, Formatting.Indented);

                    string path = WorkFlowName + ".json";
                    File.WriteAllText(path, json);
                    #endregion
                    ///数据库入库
                    ///

                    DataCollectionWorkFlowConfig model = new DataCollectionWorkFlowConfig();
                    model.DeviceID = eventModel.DeviceModel.ID;
                    model.CompentID = eventModel.DeviceComponent.ID;
                    model.WorkFlowName = WorkFlowName;
                    model.ID = Guid.NewGuid();
                    model.Rules = dbrules;
                    var dbres = _dataCollectionRuleConfigService.AddData(model) > 0;

                    if (dbres)
                    {
                        Message = "添加成功";

                    }
                }
                else
                {
                    Message = $"{WorkFlowName} 没有制定规则";

                }
          

          

        }
        #endregion





        private string _SelectRule;
        /// <summary>
        /// Combobox 选中的规则
        /// </summary>
        public string SelectRule
        {
            get { return _SelectRule; }
            set
            {


                if (_SelectRule != value&&value!=null)
                {
                    //在此进行数据的存储 存储已经
                    LoadAlreayRuleData();

                }
                ///在这里需要添加加载不同状态规则的数据  需要创建相关的规则信息
                SetProperty(ref _SelectRule, value);
               
            }
        }




        #region OPCUA属性 及其方法


        private  void LoadOPCUAModel() { 
        
        
           var data= _dataCollectionOPCUAConfigService1.GetData().Where(e=>e.CompentID==this.eventModel.DeviceComponent.ID).FirstOrDefault();
            if (data!=null)
            {
                 this.OPCUAModel = data;

                this.Url= data.Url;
                this.OPCUAName = data.OPCUAName;

            }
            else
            {
                this._OPCUAModel = null;
                this.Url = null;
                this.OPCUAName = null;
            }

        }



        private void SaveOPCUAModel() 
        {
            if (this.OPCUAModel != null) 
            { 
            
            this.OPCUAModel.OPCUAName= this.OPCUAName;
                this.OPCUAModel.Url= this.Url;

                _dataCollectionOPCUAConfigService1.UpdateData(this.OPCUAModel);




            }
            else
            {
                DataCollectionOPCUAConfig mode=new DataCollectionOPCUAConfig ();
                mode.ID=Guid.NewGuid();
                mode.CompentID=eventModel.DeviceComponent.ID;   
                mode.DeviceID=this.eventModel.DeviceModel.ID;
                mode.OPCUAName=this.OPCUAName;
                mode.Url= this.Url;
                _dataCollectionOPCUAConfigService1.AddData(mode);
                this.OPCUAModel = mode;
            }
        
        
        
        }
        private string _Url;
        public string Url
        {
            get { return _Url; }
            set { SetProperty(ref _Url, value); }
        }

        private string _OPCUAName;
        public string OPCUAName
        {
            get { return _OPCUAName; }
            set { SetProperty(ref _OPCUAName, value); }
        }






        private DataCollectionOPCUAConfig _OPCUAModel;
        public DataCollectionOPCUAConfig OPCUAModel
        {
            get { return _OPCUAModel; }
            set { SetProperty(ref _OPCUAModel, value); }
        }



        #endregion





    }



    public class ConditionItem : BindableBase
    {

        public bool JudgeDataType(string datatypename, string value)
        {
            #region 类型判断 其他地方要用

            bool flag = false;

            //  首先需要判断变量的类型
            var datatype = DataTypeEnumExtensions.GetCollectionTypeByDescription(datatypename);


            switch (datatype)
            {
                case DataTypeEnum.int16:

                    return Int16.TryParse(value, out Int16 int16res);
                case DataTypeEnum.int32:
                    return Int32.TryParse(value, out Int32 int32res);

                case DataTypeEnum.int64:
                    return Int64.TryParse(value, out Int64 int64res);

                case DataTypeEnum.Floot:
                    return float.TryParse(value, out float floatres);

                case DataTypeEnum.Double:
                    return double.TryParse(value, out double doubleres);
                case DataTypeEnum.Bool:

                    return bool.TryParse(value, out bool boolres);
                case DataTypeEnum.String:
                    return true;
                default:
                    return flag;
            }

            #endregion




        }

        private bool _IsCkeck;

        public bool IsCheck
        {
            get { return _IsCkeck; }
            set
            {
                SetProperty(ref _IsCkeck, value);

            }
        }


        private string _PLCProperty;

        public string PLCProperty
        {
            get { return _PLCProperty; }
            set
            {

                SetProperty(ref _PLCProperty, value);
            }
        }

        private string _VarType;

        public string VarType
        {
            get { return _VarType; }
            set
            {
                SetProperty(ref _VarType, value);

            }
        }


        private Guid _PropertyID;

        public Guid PropertyID
        {
            get { return _PropertyID; }
            set { _PropertyID = value; }
        }

        private string _Value;

        public string Value
        {
            get { return _Value; }
            set
            {
                SetProperty(ref _Value, value);
                if (value != null&&VarType!=null)
                {


                    if (JudgeDataType(VarType, value))
                    {
                       
                        TipMessage = "输入正确";
                    }
                    else
                    {
                        TipMessage = "输入错误";
                    }
                }

            }
        }



        private string _TipMessage;

        public string TipMessage
        {
            get { return _TipMessage; }
            set
            {
                SetProperty(ref _TipMessage, value);
            }




        }





    }
}
